package com.wl.wuliu.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wl.wuliu.entity.*;
import com.wl.wuliu.exception.GlobalExceptionHandler;
import com.wl.wuliu.mapper.DriverMapper;
import com.wl.wuliu.mapper.FinanceMapper;
import com.wl.wuliu.mapper.TruckMapper;
import com.wl.wuliu.result.AjaxResult;
import com.wl.wuliu.service.DriverService;
import com.wl.wuliu.service.FinanceService;
import com.wl.wuliu.service.SysUserService;
import com.wl.wuliu.service.TruckService;
import com.wl.wuliu.utils.DateUtils;
import com.wl.wuliu.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author: gutaozhen
 * @Date: 2024/5/15
 */
@Service
public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> implements FinanceService {
    public static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @Autowired
    private FinanceMapper financeMapper;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private TruckMapper truckMapper;

    @Override
    public List<FinanceResult> findList(QueryEntity queryEntity) {

        List<FinanceResult> list = financeMapper.findList(queryEntity);
        return list;
    }

    @Override
    public void saveFinance(String truckId) {

        Finance finance = new Finance();
        finance.setTruckId(truckId);
        finance.preInsert();
        save(finance);
        log.info("保存财务信息成功，id为：{}", finance.getId());

    }

    @Override
    public AjaxResult updateFinance(Finance finance) {

        log.info("修改财务信息，修改前的信息为：{}", finance);

        //计算联络员的利润
        Truck truck = truckMapper.selectById(finance.getTruckId());
        finance.setProfit((finance.getPrice().subtract(finance.getGiveCar()).multiply(truck.getUninstallWeight()).add(finance.getInfoAmount())));
        finance.preUpdate();
        updateById(finance);
        log.info("修改财务信息成功");

        return AjaxResult.success("修改成功！");
    }

    /**
     * 计算联络员的利润
     */
/*    private void setFinanceProfit(Finance finance) {
        Truck truck = truckMapper.selectById(finance.getTruckId());
        if (truck != null) {
            SysUser sysUser = sysUserService.findSysUser(new SysUser(truck.getUserId()));
            if ("guanli".equals(sysUser.getRoleKey())) {
                //计算管理员的利润
                finance.setProfit((finance.getPrice()-finance.getGiveCar()) * truck.getUninstallWeight() + finance.getInfoAmount());
            }else {
                //计算联络员的利润
                finance.setProfit(((finance.getPrice()-finance.getGiveCar()) * truck.getUninstallWeight() + finance.getInfoAmount()) / 2);
            }
        }
    }*/

    @Override
    public AjaxResult deleteFinance(String id) {

        removeById(id);
        log.info("删除财务信息成功，id为：{}", id);

        return AjaxResult.success("删除成功！");
    }

    @Override
    public FinanceResult getFinance(String id) {

        FinanceResult financeResult = financeMapper.findFinance(id);

        return financeResult;
    }

    @Override
    public List<StatisticsResult> statisticsTotalProfit(String startTime, String endTime,String dateType) {

        List<String> dateArr = new ArrayList<>();

        //填入默认查询时间（默认七天）
        if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
            Date nowDate = new Date();
            Date addDateDays = DateUtils.addDateDays(nowDate, -7);
            endTime = DateUtils.format(nowDate, "yyyy-MM-dd");
            startTime = DateUtils.format(addDateDays, "yyyy-MM-dd");
            for (int i=7;i>0;i--) {
                dateArr.add(DateUtils.format(DateUtils.addDateDays(DateUtils.stringToDate(endTime, "yyyy-MM-dd"), -i)));
            }
            dateArr.add(endTime);
            dateType = "day";
        }else {
            if ("day".equals(dateType)) {
                Date startDate = DateUtils.stringToDate(startTime, "yyyy-MM-dd");
                Date endDate = DateUtils.stringToDate(endTime, "yyyy-MM-dd");
                int betweenDay = (int) DateUtil.betweenDay(startDate,endDate, true);
                for (int i=betweenDay;i>0;i--) {
                    dateArr.add(DateUtils.format(DateUtils.addDateDays(endDate, -i)));
                }
                dateArr.add(endTime);
            }else if ("month".equals(dateType)) {
                Date startDate = DateUtils.stringToDate(startTime, "yyyy-MM");
                Date endDate = DateUtils.stringToDate(endTime, "yyyy-MM");
                int betweenMonth = (int) DateUtil.betweenMonth(startDate,endDate, true);
                for (int i=betweenMonth;i>0;i--) {
                    dateArr.add(DateUtils.format(DateUtils.addDateMonths(endDate, -i), "yyyy-MM"));
                }
                dateArr.add(endTime);
                startTime += "-01";
                endTime += "-31";
            }else if ("year".equals(dateType)) {
                Date startDate = DateUtils.stringToDate(startTime, "yyyy");
                Date endDate = DateUtils.stringToDate(endTime, "yyyy");
                int betweenYear = (int) DateUtil.betweenYear(startDate,endDate, true);
                for (int i=betweenYear;i>0;i--) {
                    dateArr.add(DateUtils.format(DateUtils.addDateYears(endDate, -i), "yyyy"));
                }
                dateArr.add(endTime);
                startTime += "-01-01";
                endTime += "-12-31";
            }
        }

        List<StatisticsResult> statisticsResultArr;
        List<StatisticsResult> statisticsResultList = financeMapper.statisticsTotalProfit(startTime, endTime, dateType);
        if (dateArr.size() != statisticsResultList.size()) {
            statisticsResultArr = new ArrayList<>();
            StatisticsResult statisticsResult;
            if (statisticsResultList.size() == 0) {
                for (int i=0;i< dateArr.size();i++) {
                    statisticsResult = new StatisticsResult();
                    statisticsResult.setName(dateArr.get(i));
                    statisticsResult.setValue("0");
                    statisticsResultArr.add(statisticsResult);
                }
            }else {
                for (int i=0,j=0;i< dateArr.size() && j < statisticsResultList.size();i++) {
                    if (!dateArr.get(i).equals(statisticsResultList.get(j).getName())) {
                        statisticsResult = new StatisticsResult();
                        statisticsResult.setName(dateArr.get(i));
                        statisticsResult.setValue("0");
                        statisticsResultArr.add(statisticsResult);
                    }else {
                        statisticsResultArr.add(statisticsResultList.get(j));
                        j++;
                    }
                }
            }
        }else {
            statisticsResultArr = statisticsResultList;
        }

        return statisticsResultArr;
    }

    @Override
    public Map<String,Object> statisticsProfit(String startTime, String endTime,String dateType,String userId) {
        //默认查询的角色为管理员
        String roleKey = "guanli";
        String nickName;
        List<String> dateArr = new ArrayList<>();

        //默认查询管理员的利润
        if (StringUtils.isEmpty(userId)) {
            SysUser sysUser = new SysUser();
            sysUser.setRoleKey("guanli");
            List<SysUser> list = sysUserService.findList(sysUser);
            if (!list.isEmpty()) {
                userId = list.get(0).getId();
                nickName = list.get(0).getNickName();
            }else {
                return AjaxResult.error("没有找到相关的人员信息");
            }
        }else {
            //查询对应人员的角色
            SysUser sysUser = sysUserService.findSysUser(new SysUser(userId));
            if (sysUser != null) {
                roleKey = sysUser.getRoleKey();
                nickName = sysUser.getNickName();
            }else {
                return AjaxResult.error("没有找到相关的人员信息");
            }

        }

        //填入默认查询时间（默认七天）
        if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
            Date nowDate = new Date();
            Date addDateDays = DateUtils.addDateDays(nowDate, -7);
            endTime = DateUtils.format(nowDate, "yyyy-MM-dd");
            startTime = DateUtils.format(addDateDays, "yyyy-MM-dd");
            for (int i=7;i>0;i--) {
                dateArr.add(DateUtils.format(DateUtils.addDateDays(DateUtils.stringToDate(endTime, "yyyy-MM-dd"), -i)));
            }
            dateArr.add(endTime);
            dateType = "day";
        }else {
            if ("day".equals(dateType)) {
                Date startDate = DateUtils.stringToDate(startTime, "yyyy-MM-dd");
                Date endDate = DateUtils.stringToDate(endTime, "yyyy-MM-dd");
                int betweenDay = (int) DateUtil.betweenDay(startDate,endDate, true);
                for (int i=betweenDay;i>0;i--) {
                    dateArr.add(DateUtils.format(DateUtils.addDateDays(endDate, -i)));
                }
                dateArr.add(endTime);
            }else if ("month".equals(dateType)) {
                Date startDate = DateUtils.stringToDate(startTime, "yyyy-MM");
                Date endDate = DateUtils.stringToDate(endTime, "yyyy-MM");
                int betweenMonth = (int) DateUtil.betweenMonth(startDate,endDate, true);
                for (int i=betweenMonth;i>0;i--) {
                    dateArr.add(DateUtils.format(DateUtils.addDateMonths(endDate, -i), "yyyy-MM"));
                }
                dateArr.add(endTime);
                startTime += "-01";
                endTime += "-31";
            }else if ("year".equals(dateType)) {
                Date startDate = DateUtils.stringToDate(startTime, "yyyy");
                Date endDate = DateUtils.stringToDate(endTime, "yyyy");
                int betweenYear = (int) DateUtil.betweenYear(startDate,endDate, true);
                for (int i=betweenYear;i>0;i--) {
                    dateArr.add(DateUtils.format(DateUtils.addDateYears(endDate, -i), "yyyy"));
                }
                dateArr.add(endTime);
                startTime += "-01-01";
                endTime += "-12-31";
            }
        }

        List<StatisticsResult> statisticsResultList = financeMapper.statisticsProfit(startTime, endTime,dateType,userId,roleKey);
        List<StatisticsResult> statisticsResultArr;
        if (dateArr.size() != statisticsResultList.size()) {
            statisticsResultArr = new ArrayList<>();
            StatisticsResult statisticsResult;
            if (statisticsResultList.size() == 0) {
                for (int i=0;i< dateArr.size();i++) {
                    statisticsResult = new StatisticsResult();
                    statisticsResult.setName(dateArr.get(i));
                    statisticsResult.setValue("0");
                    statisticsResultArr.add(statisticsResult);
                }
            }else {
                for (int i=0,j=0;i< dateArr.size() && j < statisticsResultList.size();i++) {
                    if (!dateArr.get(i).equals(statisticsResultList.get(j).getName())) {
                        statisticsResult = new StatisticsResult();
                        statisticsResult.setName(dateArr.get(i));
                        statisticsResult.setValue("0");
                        statisticsResultArr.add(statisticsResult);
                    }else {
                        statisticsResultArr.add(statisticsResultList.get(j));
                        j++;
                    }
                }
            }
        }else {
            statisticsResultArr = statisticsResultList;
        }
        Map<String,Object> data = new HashMap<>();
        data.put("name",nickName);
        List<String> nameList = statisticsResultArr.stream().map(StatisticsResult::getName).collect(Collectors.toList());
        data.put("date",nameList);
        List<String> valueList = statisticsResultArr.stream().map(StatisticsResult::getValue).collect(Collectors.toList());
        data.put("profit",valueList);

        return data;
    }

    private void setStartEndTime() {

    }


    @Override
    public void export(QueryEntity queryEntity,HttpServletResponse response) throws IOException {

        //填入默认查询时间（当天）
        if (StringUtils.isEmpty(queryEntity.getEndTime()) || StringUtils.isEmpty(queryEntity.getEndTime())) {
            Date nowDate = new Date();
            String nowDateStr = DateUtils.format(nowDate, "yyyy-MM-dd");
            queryEntity.setStartTime(nowDateStr);
            queryEntity.setEndTime(nowDateStr);
        }

        List<TruckExport> truckExports = financeMapper.exportTruck(queryEntity);

        OutputStream outputStream=response.getOutputStream();
        try {
            //设置内容类型
            response.setContentType("application/vnd.vnd.ms-excel");
            //设置编码格式
            response.setCharacterEncoding("utf-8");
            //设置导出文件名称（避免乱码）
            String fileName = URLEncoder.encode("运输车信息.xlsx", "UTF-8");
            // 设置响应头
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);

            //这个实现方式非常简单直接，使用EasyExcel的write方法将查询到的数据进行处理，以流的形式写出即可
            EasyExcel.write(outputStream,TruckExport.class)//对应的导出实体类
                    .excelType(ExcelTypeEnum.XLSX)//excel文件类型，包括CSV、XLS、XLSX
                    .sheet("Sheet1")//导出sheet页名称
                    .doWrite(truckExports); //查询获取的数据集合List<T>，转成excel
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            outputStream.flush();
            outputStream.close();
        }
    }
}
